# 元类的定义：元类就是创建类的类

# 定义一个元类方法，声明的Person类指定元类方法为 UpperMetaClass，
# 将Person类的非私有属性（不是__开头的方法） 名称全部替换成大写的

# 类的方式 写一个元类的实现，类对象的父类是type，那么 UpperMetaClass的父类是 type
class UpperMetaClass(type):

    # 第一种写法 和 03定义元类1.py 类似。
    # def __new__(cls, class_name, class_parent, class_attrs):
    #     new_attrs = {}
    #     for name, value in class_attrs.items():
    #         if not name.startswith('__'):
    #             new_attrs[name.upper()] = value
    #         else:
    #             new_attrs[name] = value
    #
    #     return type.__new__(cls, class_name, class_parent, new_attrs)

    def __new__(cls, class_name, class_parent, class_attrs):
        # 第二种写法，得到一个生成器，再转换成一个字典
        new_attrs = dict(
            (name, value) if name.startswith('__') else (name.upper(), value) for name, value in class_attrs.items())
        return type.__new__(cls, class_name, class_parent, new_attrs)


class Person(object, metaclass=UpperMetaClass):
    name = '张三'
    __age = 20


if __name__ == '__main__':
    p1 = Person()
    print(p1.__class__)  # <class '__main__.Person'>

    # print(p1.name) # 神奇：p1.name 报错了
    print(p1.NAME)  # 神奇：p1.NAME 可以打印出属性的值
    print(Person.__class__)  # <class 'type'>

    print(hasattr(Person, 'name'))  # False
    print(hasattr(Person, 'NAME'))  # True
